#include "pic.h"

inline
void outb( unsigned short port, unsigned char val )
{
  asm volatile( "outb %0, %1"
		: : "a"(val), "Nd"(port) );
}

inline
unsigned char inb(unsigned short port)
{
  unsigned char ret;
  asm volatile( "inb %1, %0"
		: "=a"(ret) : "Nd"(port) );
  return ret;
}

static void timer_initialization(void)
{
  // configure timer
  outb(0x43, 0b00110100);

  // set ticking frequency
  unsigned char f = (unsigned char) 1193182 / 100;
  outb(0x40, f);

  // Enable timer IRQ
  unsigned char state = inb(0x21);
  outb(0x21, state & 0b11111110);
}

static void keyboard_initialization(void)
{
  // Enable keyboard IRQ
  unsigned char state = inb(0x21);
  outb(0x21, state & 0b11111101);
}

void pic_initialization(void)
{
  // ICW1
  outb(0x20, 0x11);
  outb(0xA0, 0x11);

  // ICW2
  outb(0x21, 0x40);
  outb(0xA1, 0x50);

  // ICW3
  outb(0x21, 0x40);
  outb(0xA1, 0x2); // Might be 0x1

  // ICW4
  outb(0x21, 0x01);
  outb(0xA1, 0x01);

  // Mask all interrupts
  outb(0x21, 0xFF);
  outb(0xA1, 0xFF);

  timer_initialization();
  keyboard_initialization();

  // Enable hardware interuptions
  asm volatile ("sti");
}
